package com.motiontheory.inttest;

import com.jayway.restassured.RestAssured;
import com.jayway.restassured.path.json.JsonPath;
import com.jayway.restassured.response.Header;
import com.jayway.restassured.response.Response;
import com.jayway.restassured.specification.RequestSpecification;
import org.apache.commons.codec.binary.Base64;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;

import java.io.File;
import java.io.FileReader;
import java.util.Date;
import java.util.Properties;

public class BaseClass {
	
	protected Properties props;
	protected String filesDir;
	protected String avatarsDir;
	
    @BeforeClass
    @Parameters({"configFile"})
	public void setUp(@Optional String configFile) throws Exception {
		if (configFile == null) {
			configFile = System.getProperty("configFile");
		}
		if (configFile == null) {
			configFile = System.getenv("configFile");
		}
		if (configFile == null) {
			configFile = "/home/efrolova/efrolova/mirada/pop-integration-test/application.properties";
		}
		props = new Properties();
		props.load(new FileReader(configFile));
		
		RestAssured.baseURI = props.getProperty("baseUrl", "http://192.168.8.227");
		RestAssured.port = Integer.parseInt(props.getProperty("port", "80"));

		filesDir = props.getProperty("filesDir", "/home/efrolova/efrolova/mirada/TestScene/");
		avatarsDir = props.getProperty("avatarsDir", "/home/efrolova/efrolova/mirada/TestImage/");
		
    }
   
    // Base64 encode
 	public String encodeToBase64(String decString) {
 		Base64 base64 = new Base64();
 		byte[] encPass = base64.encode(decString.getBytes());
 		return new String(encPass);
 	}
 	
 	// Take a random image from a directory
 	public File extractSceneImage() {
 		File dir = new File(filesDir);
 		String[] filesList = dir.list();
 		File scene = new File(filesDir + filesList[((int) (Math.random() * 1000)) % (filesList.length)]);
 		return scene;
 	}

 	// Take a random avatar from a directory
 	public File extractAvatar() {
 		File dir = new File(avatarsDir);
 		String[] filesList = dir.list();
 		File avatar = new File(avatarsDir + filesList[((int) (Math.random() * 1000)) % (filesList.length)]);
 		return avatar;
 	}

	// String of random valid characters of the specified length
 	protected String randomString(int length) {
		String randText = "";
		for(int i = 0; i < length; i++) {
			if (((((int) (Math.random() * 100)) % 7) == 2) && (i != 0) && (i != length - 1)) {
				randText += " ";
			}
			else {
				char rundomChar = ((((int) (Math.random() * 100)) % 2) == 1) ?
						((char) ((((int) (Math.random() * 1000)) % 26) + 97)) : ((char) ((((int) (Math.random() * 1000)) % 26) + 65));
						// диапозон маленьких  97<=х<=122, больших  65<=х<=90 (' ':32)
						randText += Character.toString(rundomChar);
			}
		}
		return randText;
	}
    protected String name="test055";
    protected String pass= "test055";
    protected String e_mail="@example.ru";
    protected String tag_line="i am test test055";
    protected String nameError="error";
   protected Date date = new Date();
    protected long createdAt= date.getTime() / 1000;
    protected void OptimazeUser( MockUserData[] array){
    int FirstInd=1;
    int EndInd=100;
       // MockUserData= new String[FirstInd];
        for(int i = FirstInd; i < EndInd; i++) {
           array[i] = new MockUserData(name+i,pass+i, name+i+e_mail, tag_line+i);
        }
    }
//    protected void OptimazeScene ( MockScene[] array){
//        int FirstInd=1;
//        int EndInd=10;
//        // MockUserData= new String[FirstInd];
//        for(int i = FirstInd; i < EndInd; i++) {
//            array[i] = new MockScene(name+i,createdAt);
//        }
//    }



 	
//--------------------------------------- METHODS ------------------------------------------------------------------------ 	
    
    // GET ping (/ping)
	public boolean ping() {
		String json = RestAssured.get("/ping").asString();
		final Boolean ok = JsonPath.from(json).get("ok");
		return ok;
	}
	
	// GET exists user (/user/{username}/exists)
	public boolean existsUser(String userName) {
		String json = RestAssured.get("/user/" + userName + "/exists").asString();
		Boolean ok = JsonPath.from(json).get("exists");
		if(ok == null){
			ok = false;
		}
		return ok;
	}
	
	// POST User create (/user/)
	protected JsonPath postCreateUser(MockUserData user) {
		RequestSpecification rSpecPostUser = RestAssured.given().body(user.toJson()).contentType("application/json;charset=utf-8");
		Response respPostUser = rSpecPostUser.post("/user/");
//		Response respPostUser = rSpecPostUser.post("/user/{userName}", user.getUserName()); //<- старье  !!!!!!!!!!!!!
		JsonPath jsonRespPostUser = respPostUser.getBody().jsonPath();
		return jsonRespPostUser;
	}

	// GET User (/user)
	protected JsonPath getUser(String userName, String pass) {
		Header authHeader = new Header("Authorization", "Basic " + encodeToBase64(userName + ":" + pass));
		RequestSpecification rSpecGetUser = RestAssured.given().header(authHeader);
		Response respGetUser = rSpecGetUser.get("/user");
//		Response respGetUser = rSpecGetUser.get("/user/{userName}", userName); // <- старье !!!!!!!!!!!!!!!!!!!!!!!!
		JsonPath jsonRespGetUser = respGetUser.getBody().jsonPath();
		return jsonRespGetUser;
	}

	// PUT User update (/user/{userId})
	protected JsonPath putUpdateUser(String userName, String oldPass, MockUserData mockUserNew) {
		Header authHeader = new Header("Authorization", "Basic " + encodeToBase64(userName + ":" + oldPass));
		RequestSpecification rSpecPutUser = RestAssured.given().body(mockUserNew.toJson()).contentType("application/json;charset=utf-8").header(authHeader);
		Response respPutUser = rSpecPutUser.put("/user");
		JsonPath jsonRespPutUser = respPutUser.getBody().jsonPath();
		return jsonRespPutUser;
	}
	
	// GET Retrieve decorated user's profile (/user/{userId}/profile)
	protected JsonPath getUserProfile(String sourceUserName, String sourceUserPass, String targetUserName) {
		Header authHeader = new Header("Authorization", "Basic " + encodeToBase64(sourceUserName + ":" + sourceUserPass));
		RequestSpecification rSpec = RestAssured.given().header(authHeader);
		Response response = rSpec.get("/user/{userId}/profile", targetUserName);
//		Response response = rSpec.get("/user/{targetUserId}/profile/user/{viewerUserId}", targetUserName, sourceUserName);	// <- старье !!!!!!!!!!!!!!!!!!!!!	
		JsonPath jsonResp = response.getBody().jsonPath();
		return jsonResp;
	}
	
	// POST Create Subscription (/subscription/to/user/{userId})
	protected JsonPath postSubscriptionToUser(String sourceUserName, String sourceUserPass, String targetUserName) {
		Header authHeader = new Header("Authorization", "Basic " + encodeToBase64(sourceUserName + ":" + sourceUserPass));
		RequestSpecification rSpec = RestAssured.given().header(authHeader);
		Response response = rSpec.post("/subscription/to/user/{userId}", targetUserName);		
//		Response response = rSpec.post("/subscription/user/{userId}/user/{targetUserId}", sourceUserName, targetUserName);	// <- старье !!!!!!!!!!!!!!!!!!	
		JsonPath jsonResp = response.getBody().jsonPath();
		return jsonResp;
	}
	 // \/
	// POST Create a new scene (/scene/)
	protected JsonPath postNewScene(String UserName, String userPass, MockScene scene) {
		Header authHeader = new Header("Authorization", "Basic " + encodeToBase64(UserName + ":" + userPass));
		RequestSpecification rSpec = RestAssured.given().header(authHeader).multiPart("jsonData", scene.toJson()).multiPart("sceneImage", extractSceneImage());
		Response response = rSpec.post("/scene/");
		JsonPath jsonResp = response.getBody().jsonPath();
		return jsonResp;
	}
	
	// POST Set emoticon (/scene/{sceneId}/emoticon)
	protected JsonPath postEmoticon(String UserName, String userPass, String sceneId, int type) {
		Header authHeader = new Header("Authorization", "Basic " + encodeToBase64(UserName + ":" + userPass));
		RequestSpecification rSpec = RestAssured.given().header(authHeader).body("{\"emoticonType\":" + type + "}").contentType("application/json;charset=utf-8");
		Response response = rSpec.post("/scene/{sceneId}/emoticon", sceneId);
//		Response response = rSpec.post("/scene/{sceneId}/user/{userId}/emoticon", sceneId, UserName);	// <- старье !!!!!!!!!!!!!!!!!!	
		JsonPath jsonResp = response.getBody().jsonPath();
		return jsonResp;
	}
	
	// POST Set user image (/user/{userId}/image)
	protected JsonPath postAvatar(String UserName, String userPass) {
		Header authHeader = new Header("Authorization", "Basic " + encodeToBase64(UserName + ":" + userPass));
		RequestSpecification rSpec = RestAssured.given().header(authHeader).multiPart("userImage", extractAvatar());
		Response response = rSpec.post("/user/{userId}/image", UserName);
		JsonPath jsonResp = response.getBody().jsonPath();
		return jsonResp;
	}
	
	// DELETE Remove user image (/user/{userId}/image)
	protected JsonPath deleteAvatar(String UserName, String userPass) {
		Header authHeader = new Header("Authorization", "Basic " + encodeToBase64(UserName + ":" + userPass));
		RequestSpecification rSpec = RestAssured.given().header(authHeader);
		Response response = rSpec.delete("/user/{userId}/image", UserName);
		JsonPath jsonResp = response.getBody().jsonPath();
		return jsonResp;
	}
	
	// GET Retrieve a scene’s metadata (/scene/{sceneId})
	protected JsonPath getScene(String UserName, String userPass, String sceneId) {
		Header authHeader = new Header("Authorization", "Basic " + encodeToBase64(UserName + ":" + userPass));
		RequestSpecification rSpec = RestAssured.given().header(authHeader);
		Response response = rSpec.get("/scene/{sceneId}", sceneId);
		JsonPath jsonResp = response.getBody().jsonPath();
		return jsonResp;
	}
	
	// POST Add a comment to a scene (/scene/{sceneId}/comment/)
	protected JsonPath postComment(String UserName, String userPass, String sceneId, String textComment) {
		Header authHeader = new Header("Authorization", "Basic " + encodeToBase64(UserName + ":" + userPass));
		Date date = new Date();
		long timeStamp = date.getTime() / 1000;
		String bodyJ = "{\"commentData\":{\"id\":\"" + UserName + "-" + timeStamp +
				"\",\"createdBy\":\"" + UserName +
				"\",\"createdAt\":" + timeStamp +
				",\"text\":\"" + textComment +
				"\"}}";
		RequestSpecification rSpec = RestAssured.given().header(authHeader).body(bodyJ).contentType("application/json;charset=utf-8");
		Response response = rSpec.post("/scene/{sceneId}/comment", sceneId);
		JsonPath jsonResp = response.getBody().jsonPath();
		return jsonResp;
	}
	
	// DELETE Delete a scene (/scene/{sceneId})
	protected JsonPath deleteScene(String UserName, String userPass, String sceneId) {
		Header authHeader = new Header("Authorization", "Basic " + encodeToBase64(UserName + ":" + userPass));
		RequestSpecification rSpec = RestAssured.given().header(authHeader);
		Response response = rSpec.delete("/scene/{sceneId}", sceneId);
		JsonPath jsonResp = response.getBody().jsonPath();
		return jsonResp;
	}
	
	// GET Get a List of the comments on a scene (/scene/{sceneId}/comment/)
	protected JsonPath getCommentsOfScene(String UserName, String userPass, String sceneId) {
		Header authHeader = new Header("Authorization", "Basic " + encodeToBase64(UserName + ":" + userPass));
		RequestSpecification rSpec = RestAssured.given().header(authHeader);
		Response response = rSpec.get("/scene/{sceneId}/comment/?limit=20", sceneId);
//		Response response = rSpec.get("/scene/{sceneId}/comment/skip/0/limit/500", sceneId);		//  <- старье !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!	
		JsonPath jsonResp = response.getBody().jsonPath();
		return jsonResp;
	}

	// DELETE Delete a comment (/scene/{sceneId}/comment/{commentId})
	protected JsonPath deleteComment(String UserName, String userPass, String sceneId, String commentId) {
		Header authHeader = new Header("Authorization", "Basic " + encodeToBase64(UserName + ":" + userPass));
		RequestSpecification rSpec = RestAssured.given().header(authHeader);
		Response response = rSpec.delete("/scene/{sceneId}/comment/{commentId}", sceneId, commentId);
		JsonPath jsonResp = response.getBody().jsonPath();
		return jsonResp;
	}
	
	// GET Retrieve the feed (/scene/feed/?view=grid&sort=newest&limit=20)
	protected JsonPath getFeed(String UserName, String userPass, String view, String sort, String limit) {
		Header authHeader = new Header("Authorization", "Basic " + encodeToBase64(UserName + ":" + userPass));
		RequestSpecification rSpec = RestAssured.given().header(authHeader);
		Response response = rSpec.get("/scene/feed/?view={view}&sort={sort}&limit={limit}", view, sort, limit);
		JsonPath jsonResp = response.getBody().jsonPath();
		return jsonResp;
	}
	
}
